﻿using System.Collections.Generic;
using System.Linq;
using CID.Domain.Operations;
using CID.Web.Models.Development;
using Newtonsoft.Json;

namespace CID.Web.Models.Operations
{
    public class ServerRoleViewModel : BaseDescribedViewModel<IServerRole>, IAjaxEnabledViewModel
    {
        #region Properties
        public bool Enabled { get; set; }
        public List<ServerAssignmentViewModel> Assignments { get; set; }

        [JsonIgnore]
        public List<ComponentViewModel> Components { get; set; }

        public string PostUrl { get; set; }
        #endregion

        public ServerRoleViewModel() : base() 
        {
            Assignments = new List<ServerAssignmentViewModel>();
            Components = new List<ComponentViewModel>();
        }
        
        public ServerRoleViewModel(IServerRole model) : base(model)
        {
            Assignments = new List<ServerAssignmentViewModel>();
            Components = new List<ComponentViewModel>();

            Enabled = model.Enabled;

            foreach (var assignment in model.Assignments)
                Assignments.Add(new ServerAssignmentViewModel(assignment));

            foreach (var component in model.Components)
                Components.Add(new ComponentViewModel(component));
        }

        public override void UpdateModel(IServerRole model)
        {
            base.UpdateModel(model);
            model.Enabled = Enabled;

            foreach (var removedAssignment in RemovedAssignments)
            {
                var assignment = model.Assignments.SingleOrDefault(x => x.Id == removedAssignment.Id);
                model.RemoveAssignment(assignment);
            }

            foreach (var insertedAssignment in InsertedAssignments)
                model.Assign(GetServer(insertedAssignment), GetEnvironment(insertedAssignment));
        }

        private IEnumerable<ServerAssignmentViewModel> InsertedAssignments
        {
            get { return Assignments.Where(x => ((x.Id == 0) && !x._destroy)); }
        }

        private IEnumerable<ServerAssignmentViewModel> RemovedAssignments
        {
            get { return Assignments.Where(x => ((x.Id != 0) && x._destroy)); }
        }

        #region Edition Helper Members
        #region Server helper members
        private IEnumerable<Server> availableServers;

        public void SetAvailableServers(IEnumerable<Server> availableServers)
        {
            this.availableServers = availableServers.ToArray();
        }
        #endregion

        #region Environment helper members
        private IEnumerable<Environment> availableEnvironments;

        public void SetAvailableEnvironments(IEnumerable<Environment> availableEnvironments)
        {
            this.availableEnvironments = availableEnvironments.ToArray();
        }
        #endregion

        public ServerAssignmentViewModel NewServerAssignment()
        {
            var result = new ServerAssignmentViewModel();
            result.SetAvailableServers(availableServers);
            result.SetAvailableEnvironments(availableEnvironments);

            return result;
        }

        private IServer GetServer(ServerAssignmentViewModel assignment)
        {
            return availableServers.SingleOrDefault(x => x.Id == assignment.ServerId);
        }

        private IEnvironment GetEnvironment(ServerAssignmentViewModel assignment)
        {
            return availableEnvironments.SingleOrDefault(x => x.Id == assignment.EnvironmentId);
        }

        #endregion

    }
}